package com.passioneffect.components {
	import flash.display.DisplayObjectContainer;
	import flash.display.Graphics;
	import flash.display.Sprite;
	import flash.display.Stage;
	import flash.events.Event;
	import flash.events.TimerEvent;
	import flash.geom.Rectangle;
	import flash.text.TextField;
	import flash.text.TextFormat;
	import flash.utils.Dictionary;
	import flash.utils.Timer;		

	/**
	 * @author Passion Effect
	 */
	public class Tooltip {
		static private var tf : TextField;
		static private var stage : Stage;
		static private var range:Dictionary;
		private static var showingTip:Sprite;
		private static var timers:Dictionary;
		private static var hiddenTimer:Timer;
		
		static public function init(stage:Stage):void{
			Tooltip.stage=stage;
			Tooltip.range=new Dictionary();
			timers=new Dictionary();
			hiddenTimer=new Timer(300);
			hiddenTimer.addEventListener(TimerEvent.TIMER,onHide);
		}
		
		static public function onHide(event : TimerEvent) : void {
			hiddenTimer.stop();
		}

		static public function show(txt : String,rect : Rectangle,at : DisplayObjectContainer,style:Object) : void {
			
			if(showingTip){
				hide(showingTip);
			}
			
			if(!txt)return;
	
			var tooltip : Sprite = Sprite(stage.addChild(drawTooltip(txt,style)));
			tooltip.x = stage.mouseX;
			tooltip.y = stage.mouseY;
			showingTip=tooltip;
			
			range[tooltip]={txt:txt,rect:rect,at:at};
			tooltip.addEventListener(Event.ENTER_FRAME,hitTest);

			tooltip.visible = false;
			
			if(!hiddenTimer.running){
				var timer:Timer=new Timer(style.delay*1000);
				timers[timer]=tooltip;
				timer.addEventListener(TimerEvent.TIMER,onTimer);
				timer.start();
			}else{
				tooltip.visible=true;
			}
			
		}
		
		static public function onTimer(event : TimerEvent) : void {
			Timer(event.target).removeEventListener(TimerEvent.TIMER,onTimer);
			var t:Sprite=timers[event.target];
			if(t){
				timers[event.target]=null;
				delete timers[event.target];
				t.visible=true;
			}
		}

		static private function hitTest(event : Event) : void {
			var t:Sprite=Sprite(event.target);
			var rect:Rectangle=range[t].rect;
			var at:DisplayObjectContainer=range[t].at;
			
			var mx:Number=at.mouseX;
			var my:Number=at.mouseY;
			
			if(!rect.contains(mx, my)){
				hide(t);
			}else{
				t.x=stage.mouseX;
				t.y=stage.mouseY;
			}
		}

		static public function hide(target : Sprite) : void {
			if(range[target]){
				if(target.visible){
					hiddenTimer.start();
				}
				target.removeEventListener(Event.ENTER_FRAME,hitTest);
				target.visible = false;
				stage.removeChild(target);
				if(showingTip==target)showingTip=null;
				range[target]=null;
				delete[target];
			}
		}

		static private function drawTooltip(txt : String,style:Object) : Sprite {
			var t : Sprite = new Sprite();
			var inner:Sprite=new Sprite();
			style.distance=style.distance||0;
			
			var tf:TextField=new TextField();
			var tff:TextFormat=new TextFormat();
			
			tff.size=style.fontSize||13;
			tff.font=style.font||"Arial";
			tff.color=style.color||0x000000;
			tf.embedFonts=style.embedFonts;
			
			tf.selectable=false;
			tf.text=txt;
			tf.setTextFormat(tff);
			tf.autoSize="left";
			
			if(tf.width>style.width && style.width>0){
				tf.width=style.width;
				tf.multiline=true;
				tf.wordWrap=true;
			}
			
			var offsetH:Number=style.offsetH||5;
			var offsetV:Number=style.offsetV||5;
			
			var g : Graphics = inner.graphics;
			g.lineStyle();
			g.beginFill(style.backgroundColor||0x000000,style.alpha==undefined?1:style.alpha);
			g.drawRoundRect(0, 0, tf.width+offsetH*2,tf.height+offsetV*2,5,5);
			
			var tiprect:Rectangle=new Rectangle(0,0,tf.width+offsetH*2,tf.height+offsetV*2);
			
			if(style.position=="left"){
				g.moveTo(tf.width+offsetH*2,((tf.height+offsetV*2)/2)-5);
				g.lineTo(tf.width+offsetH*2+10,(tf.height+offsetV*2)/2);
				g.lineTo(tf.width+offsetH*2,((tf.height+offsetV*2)/2)+5);
			}else if(style.position=="right"){
				g.moveTo(0,((tf.height+offsetV*2)/2)-5);
				g.lineTo(-10,(tf.height+offsetV*2)/2);
				g.lineTo(0,((tf.height+offsetV*2)/2)+5);
			}else if(style.position=="top"){
				g.moveTo(tiprect.width/2-5,tiprect.height);
				g.lineTo(tiprect.width/2+5,tiprect.height);
				g.lineTo(tiprect.width/2,tiprect.height+10);
			}else if(style.position=="bottom"){
				g.moveTo(tiprect.width/2-5,0);
				g.lineTo(tiprect.width/2+5,0);
				g.lineTo(tiprect.width/2,-10);
			}
			
			g.endFill();
			
			tf.x=offsetH;
			tf.y=offsetV;
			
			inner.addChild(tf);
			t.addChild(inner);
			
			if(style.position=="left"){
				inner.x=-inner.width-style.distance;
				inner.y=-inner.height/2;
			}else if(style.position=="right"){
				inner.x=10+style.distance;
				inner.y=-inner.height/2;
			}else if(style.position=="top"){
				inner.x=-tiprect.width/2;
				inner.y=-inner.height-style.distance;
			}else if(style.position=="bottom"){
				inner.x=-tiprect.width/2;
				inner.y=10+style.distance;
			}
			
			t.visible = false;
			return t;
		}
	}
}
